package entity

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"gorm.io/gorm"
	"shqsoft.cn/pas3ui/base"
	"shqsoft.cn/pas3ui/workflow"
	"shqsoft.cn/pas3ui/workflow/entity"
)

//SpBmbg 部门变更
type SpBmbg struct {
	ID       int       `gorm:"column:ID;AUTO_INCREMENT;primary_key" json:"id"`
	SQSJ     time.Time `gorm:"column:SQSJ" json:"sqsj"`
	SQR      int       `gorm:"column:SQR" json:"sqr"`
	SQLB     int       `gorm:"column:SQLB" json:"sqlb"`
	ORGIDY   int       `gorm:"column:OrgIDy" json:"orgidy"`
	ORGIDX   int       `gorm:"column:OrgIDx" json:"orgidx"`
	YJBD_DG  int       `gorm:"column:YJBD_DG" json:"yjbd_dg"`
	YJBD_CX  int       `gorm:"column:YJBD_CX" json:"yjbd_cx"`
	YJBD_GD  int       `gorm:"column:YJBD_GD" json:"yjbd_gd"`
	FRID     int       `gorm:"column:FRID" json:"frid"`
	WFID     int       `gorm:"column:WFID"`
	SQRNM    string    `gorm:"column:SQRNM" json:"sqrnm"`
	ORGNMY   string    `gorm:"column:OrgNMy" json:"orgnmy"`
	ORGNMX   string    `gorm:"column:OrgNMx" json:"orgnmx"`
	DDDT     time.Time `gorm:"column:DDDT" json:"dddt"`
	UID      int       `gorm:"column:UID"`
	Progress float32   `gorm:"-" json:"progress"`
	StepName string    `gorm:"-" json:"stepName"`
	Status   string    `gorm:"-" json:"status"`
	STEP     int       `gorm:"-" json:"step"`
}

//TableName SpBmbg表名
func (SpBmbg) TableName() string {
	return "T_SP_BMBG"
}

//BeforeCreate 保存前的触发器
func (s *SpBmbg) BeforeCreate(tx *gorm.DB) (err error) {
	if s.ORGIDY == s.ORGIDX && s.FRID != 2 {
		return errors.New("调入部门和调出部门不能为同一部门！")
	}
	var user User
	err = tx.First(&user, s.SQR).Error
	if err != nil {
		return err
	}
	s.ORGIDY = *user.OrganizationID
	s.SQRNM = user.Name
	if s.ID == 0 {
		var count int
		var frids []int
		err = tx.Table("T_SP_BMBG").Where(`"SQR"=?`, s.SQR).Pluck(`"FRID"`, &frids).Error
		if err != nil {
			return err
		}
		row := tx.Raw(`select count("ID") from "T_FLOW_RUN" where "ID" in (?) and "STATE"='0'`, frids).Row()
		err = row.Scan(&count)
		if err != nil {
			return err
		}
		if count > 0 {
			return fmt.Errorf("用户:%s的部门变动申请已经在审批中,请不要重复申请", user.Name)
		}
	}
	var orgy Organization
	err = tx.First(&orgy, user.OrganizationID).Error
	if err != nil {
		return err
	}
	s.ORGNMY = orgy.Name
	var orgx Organization
	err = tx.First(&orgx, s.ORGIDX).Error
	if err != nil {
		return err
	}
	s.ORGNMX = orgx.Name
	if strings.Contains(s.ORGNMY, "离职") {
		return errors.New("员工调动调入部门不能为离职部门！")
	}
	s.SQSJ = time.Now()
	row := tx.Raw(`select "DDDT" from "T_SP_BMBG" where "SQR"=? and "DDDT" is not null ORDER BY "DDDT"`, s.SQR).Row()
	var bgdt time.Time
	row.Scan(&bgdt)
	if s.DDDT.Unix() <= bgdt.Unix() {
		return fmt.Errorf("员工的业绩变更日期%s必须大于上次的业绩变更日期%s", s.DDDT.Format("20060102"), bgdt.Format("20060102"))
	}
	if s.FRID == 0 {
		ei, _ := workflow.GetEntityInfo("SpBmbg")
		s.WFID, err = ei.WfidFunc(s)
		if err != nil {
			return err
		}
		if s.WFID == 0 {
			return errors.New("获取新公司账户申请WFID失败")
		}
		runid, err := workflow.Create(s.WFID, s.UID, tx)
		if err != nil {
			return err
		}
		s.FRID = runid
	}
	if s.YJBD_DG == 3 {
		err = createFs3List(s.FRID, 1, s.SQR)
		if err != nil {
			return err
		}
	}
	if s.YJBD_CX == 3 {
		err = createFs3List(s.FRID, 2, s.SQR)
		if err != nil {
			return err
		}
	}
	if s.YJBD_GD == 3 {
		err = createFs3List(s.FRID, 3, s.SQR)
		if err != nil {
			return err
		}
	}
	return
}

func (s *SpBmbg) AfterDelete(tx *gorm.DB) (err error) {
	if s.FRID > 0 {
		return workflow.Delete(s.FRID)
	}
	return nil
}

// AfterFind 查询后触发器
func (s *SpBmbg) AfterFind(tx *gorm.DB) (err error) {
	if s.FRID == 0 {
		s.Status = "exception"
		s.StepName = "校验错误"
		return
	}
	run := entity.FlowRun{}
	if err = tx.Find(&run, s.FRID).Error; err != nil {
		tx.Rollback()
		return
	}
	wf := workflow.GetWorkFlow(run.WFID)
	if wf == nil {
		return fmt.Errorf("指定的流程ID:%d在流程配置中不存在！", run.WFID)
	}
	act := wf.GetAction(run.Step)
	if act == nil {
		return fmt.Errorf("指定的stepID:%d在流程%s配置中不存在！", run.Step, wf.Name)
	}
	count := len(wf.Actions)
	s.STEP = run.Step
	s.WFID = run.WFID
	s.StepName = act.Desc
	s.Progress = float32(act.Step*100) / float32(count)
	if s.Progress >= 100 && run.State == "0" {
		s.Progress = 95
	}
	s.Status = ""
	if run.State == "0" {
		s.Status = "active"
	} else if run.State == "2" {
		s.Status = "exception"
	} else {
		s.Status = "success"
	}
	return
}

//SpBmbgEF 获取实体类对象
func SpBmbgEF() base.EntityFunc {
	return func() interface{} {
		entity := SpBmbg{}
		return &entity
	}
}

//SpBmbgESF 获取实体类对象数组
func SpBmbgESF() base.EntitiesFunc {
	return func() interface{} {
		var entities []SpBmbg
		return &entities
	}
}
func getSpBmbgWfidSh(params interface{}) (wfid int, err error) {
	s, ok := params.(*SpBmbg)
	if ok {
		if s.SQLB == 1 {
			wfid = 13
		} else {
			wfid = 14
		}
		return
	}
	err = errors.New("运行getSpBmbgWfidSh出错,参数的类型不是SpBmbg")
	return
}
func getSpBmbgWfidSz(params interface{}) (wfid int, err error) {
	return
}
func init() {
	workflow.SetWfidFunc("getSpBmbgWfidSh", getSpBmbgWfidSh)
	workflow.SetWfidFunc("getSpBmbgWfidSz", getSpBmbgWfidSz)
	ei, err := workflow.GetEntityInfo("SpBmbg")
	if err != nil {
		panic(err)
	}
	dao := base.NewDefaultDao(SpBmbgEF(), SpBmbgESF(), nil, "my")
	filter := base.WorkFolowFilter{
		FilterColName: "FRID",
	}
	filter.SetAdditional("wfid", ei.WfidsToString())
	filter.SetAdditional("manager", ei.MgMapToString())
	dao.Fileter = &filter
	dao.Fileter.SetDB("my")
	base.DaoPoolObj.Put("SpBmbg", dao)
}
func YgddFsChange(frid int, ywlx int, yjbd int) (err error) {
	var bmbg SpBmbg
	err = base.MYDB.First(&bmbg, fmt.Sprintf(`"FRID"=%d`, frid)).Error
	if err != nil {
		return
	}
	if ywlx == 1 {
		bmbg.YJBD_DG = yjbd
	} else if ywlx == 2 {
		bmbg.YJBD_CX = yjbd
	} else if ywlx == 3 {
		bmbg.YJBD_GD = yjbd
	} else {
		err = fmt.Errorf("无效的ywlx参数, ywlx必须1对公,2储蓄,3个贷")
		return
	}
	if yjbd == 3 {
		err = createFs3List(frid, ywlx, bmbg.SQR)
		if err != nil {
			return
		}
	}
	err = base.MYDB.Save(&bmbg).Error
	return
}

func createFs3List(frid int, ywlx int, emid int) (err error) {
	var sqlStr string
	var sqlSelStr string
	if ywlx == 1 {
		sqlSelStr = `select count(*) from "T_SP_BMBG_COMP_ACCO_DIVI" where "SPID"=?`
		sqlStr = `insert into mysql.T_SP_BMBG_COMP_ACCO_DIVI(SPID,ACNO,BANO,CUNM,OPDT,UTNM,CYNM,ITNM,ACBL,OEMNO1,OEMNM1,ODSVL1,OEMNO2,OEMNM2,ODSVL2,OEMNO3,OEMNM3,ODSVL3,OEMNO4,OEMNM4,ODSVL4,OEMNO5,OEMNM5,ODSVL5,OEMNO6,OEMNM6,ODSVL6)
		select ?,b.ACNO,b.BANO,b.CUNM,b.OPDT,dictGetString('DICT_DEPT','DPNM',toUInt64(b.UTID)) UTNM,dictGetString('DICT_CUCY','name',toUInt64(b.CYNO)) CYNM,
		dictGetString('DICT_ITEM','ITNM',toUInt64(b.ITID)) ITNM,b.ACBL,
		if(a.EMID1=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID1))) EMNO1,if(a.EMID1=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID1))) EMNM1,a.DSVL1*100,
		if(a.EMID2=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID2))) EMNO2,if(a.EMID2=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID2))) EMNM2,a.DSVL2*100,
		if(a.EMID3=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID3))) EMNO3,if(a.EMID3=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID3))) EMNM3,a.DSVL3*100,
		if(a.EMID4=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID4))) EMNO4,if(a.EMID4=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID4))) EMNM4,a.DSVL4*100,
		if(a.EMID5=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID5))) EMNO5,if(a.EMID5=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID5))) EMNM5,a.DSVL5*100,
		if(a.EMID6=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID6))) EMNO6,if(a.EMID6=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID6))) EMNM6,a.DSVL6*100
		FROM
		(SELECT ACID,DIVI.EMID[1] EMID1,DIVI.DSVL[1] DSVL1,DIVI.EMID[2] EMID2,DIVI.DSVL[2] DSVL2,DIVI.EMID[3] EMID3,DIVI.DSVL[3] DSVL3,
				DIVI.EMID[4] EMID4,DIVI.DSVL[4] DSVL4,DIVI.EMID[5] EMID5,DIVI.DSVL[5] DSVL5,DIVI.EMID[6] EMID6,DIVI.DSVL[6] DSVL6
		from "T_COMP_ACCO_DIVI_ZIPPER" where "EDATE" ='2099-12-31' and has(DIVI.EMID,?)) a INNER JOIN T_COMP_ACCO b on a.ACID=b.ID`
	} else if ywlx == 2 {
		sqlSelStr = `select count(*) from "T_SP_BMBG_INDI_ACCO_DIVI" where "SPID"=?`
		sqlStr = `insert into mysql.T_SP_BMBG_INDI_ACCO_DIVI(SPID,ACNO,BANO,CUNM,OPDT,UTNM,CYNM,ITNM,ACBL,OEMNO1,OEMNM1,ODSVL1,OEMNO2,OEMNM2,ODSVL2,OEMNO3,OEMNM3,ODSVL3,OEMNO4,OEMNM4,ODSVL4)
		select ?,b.ACNO,b.BANO,b.CUNM,b.OPDT,dictGetString('DICT_DEPT','DPNM',toUInt64(b.UTID)) UTNM,dictGetString('DICT_CUCY','name',toUInt64(b.CYNO)) CYNM,
		dictGetString('DICT_ITEM','ITNM',toUInt64(b.ITID)) ITNM,b.ACBL,
		if(a.EMID1=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID1))) EMNO1,if(a.EMID1=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID1))) EMNM1,a.DSVL1*100,
		if(a.EMID2=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID2))) EMNO2,if(a.EMID2=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID2))) EMNM2,a.DSVL2*100,
		if(a.EMID3=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID3))) EMNO3,if(a.EMID3=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID3))) EMNM3,a.DSVL3*100,
		if(a.EMID4=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID4))) EMNO4,if(a.EMID4=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID4))) EMNM4,a.DSVL4*100
		FROM
		(SELECT ACID,DIVI.EMID[1] EMID1,DIVI.DSVL[1] DSVL1,DIVI.EMID[2] EMID2,DIVI.DSVL[2] DSVL2,DIVI.EMID[3] EMID3,DIVI.DSVL[3] DSVL3,
				DIVI.EMID[4] EMID4,DIVI.DSVL[4] DSVL4
		from "T_INDI_ACCO_DIVI_ZIPPER" where "EDATE" ='2099-12-31' and has(DIVI.EMID,?)) a INNER JOIN T_INDI_ACCO b on a.ACID=b.ID`
	} else {
		sqlSelStr = `select count(*) from "T_SP_BMBG_INDI_LOAN_DIVI" where "SPID"=?`
		sqlStr = `insert into mysql.T_SP_BMBG_INDI_LOAN_DIVI(SPID,EVNO,CUNM,OPDT,UTNM,ITNM,ACBL,OEMNO1,OEMNM1,ODSVL1,OEMNO2,OEMNM2,ODSVL2,OEMNO3,OEMNM3,ODSVL3,OEMNO4,OEMNM4,ODSVL4)
		select ?,b.EVNO,b.CUNM,b.releasedate,dictGetString('DICT_DEPT','DPNM',toUInt64(b.UTID)) UTNM,dictGetString('DICT_ITEM','ITNM',toUInt64(b.ITID)) ITNM,b.ACBL,
		if(a.EMID1=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID1))) EMNO1,if(a.EMID1=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID1))) EMNM1,a.DSVL1*100,
		if(a.EMID2=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID2))) EMNO2,if(a.EMID2=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID2))) EMNM2,a.DSVL2*100,
		if(a.EMID3=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID3))) EMNO3,if(a.EMID3=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID3))) EMNM3,a.DSVL3*100,
		if(a.EMID4=0,'',dictGetString('DICT_USER_DEPT','EMNO',toUInt64(a.EMID4))) EMNO4,if(a.EMID4=0,'',dictGetString('DICT_USER_DEPT','EMNM',toUInt64(a.EMID4))) EMNM4,a.DSVL4*100
		FROM
		(SELECT ACID,DIVI.EMID[1] EMID1,DIVI.DSVL[1] DSVL1,DIVI.EMID[2] EMID2,DIVI.DSVL[2] DSVL2,DIVI.EMID[3] EMID3,DIVI.DSVL[3] DSVL3,
				DIVI.EMID[4] EMID4,DIVI.DSVL[4] DSVL4
		from "T_INDI_ACCO_DIVI_ZIPPER" where "EDATE" ='2099-12-31' and has(DIVI.EMID,?)) a INNER JOIN T_INDI_LOAN b on a.ACID=b.ID`
	}
	var count int
	err = base.MYDB.Raw(sqlSelStr, frid).Row().Scan(&count)
	if err != nil {
		return
	}
	if count == 0 {
		err = base.CHDB.Exec(sqlStr, frid, emid).Error
		if err != nil {
			return
		}
	}
	return
}
